//
//  YZNewFriend.m
//  VET
//
//  Created by lixiaoyi on 2018/7/11.
//  Copyright © 2018年 YZ. All rights reserved.
//

#import "YZNewFriend.h"
#import "ChatHeader.h"
#import "YZFriendBaseCell.h"
#import "YZFriendModel.h"
#import "YZFriendVM.h"
#import "SVProgressHUD.h"
#import "SVProgressHUD+Message.h"
#import "YZDBManager.h"
#import "ClientSocket.h"
#import "YZChatUtils.h"
#import "varint.h"
#import "YZUser.h"
#import "YZNetworkConfig.h"

static NSString *flagCell = @"YZFriendBaseCell";

@interface YZNewFriend ()<UITableViewDataSource,UITableViewDelegate,ClientSocketDelegate>
@property (nonatomic, strong) UITableView *newFriendTable;
@property (nonatomic, strong) NSMutableArray *newFriendData;
@property (nonatomic, strong) YZFriendVM *viewModel;


// 所有接收到的数据大小
@property (nonatomic) NSUInteger allSize;

// 所有接收到的数据
@property (nonatomic, strong) NSMutableData *allData;

// 待读字节
@property (nonatomic) unsigned long long bufferSize;

// 缓冲区
@property (nonatomic, strong) NSMutableData *buffer;


@end

@implementation YZNewFriend

#pragma mark - life cycle
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationController.navigationBar.translucent = YES;
    [self.navigationController.navigationBar setHidden:NO];
    self.title = @"新朋友";
    [self.view addSubview:self.newFriendTable];
    
//    // 把新朋友插入或更新到数据库
//    NSUInteger lastFriendCount = [self.latestFriendArr count];
//    if (lastFriendCount > 0) {
//        for (int index = 0; index < lastFriendCount; index++) {
//            NSArray *arr = nil;
//            YZFriendModel *tempModel = self.latestFriendArr[index];
//            NSString *condition = [NSString stringWithFormat:@"targetId = %@",tempModel.targetId];
//            arr = [[YZDBManager sharedManage] queryDataFromTable:kNewFriendTable andCondition:condition];
//            if (arr.count == 0) {
//                // 插入
//                [self insertNewFriend:tempModel];
//            } else {
//                // 更新
//                NSString *setStr = [NSString stringWithFormat:@"iconUrl = '%@',name = '%@',auditStatus = '%lu'",tempModel.iconName,tempModel.name,tempModel.friendState];
//                NSString *conditionStr = [NSString stringWithFormat:@"targetId = %@",tempModel.targetId];
//                BOOL success = [[YZDBManager sharedManage] updateData:setStr table:kNewFriendTable andCondition:conditionStr];
//                if (success) {}
//            }
//        }
//    }
    
    // 获取本地新朋友的列表
    NSArray *tempArr = [[YZDBManager sharedManage] queryDataFromTable:kNewFriendTable andCondition:@""];
    [self.newFriendData addObjectsFromArray:tempArr];
    
    
    [[self rac_signalForSelector:@selector(tableView:didSelectRowAtIndexPath:) fromProtocol:@protocol(UITableViewDelegate)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@"点击了");
    }];
    
    // 待读字节数
    _bufferSize = 0;
    
    // 缓冲区
    _buffer = [NSMutableData data];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    [ClientSocket shareSocket].socketHost = [YZNetworkConfig getImDomain][@"ip"];
    [ClientSocket shareSocket].socketPort = [[YZNetworkConfig getImDomain][@"port"] integerValue];
    [[ClientSocket shareSocket] autoConnection];
    [ClientSocket shareSocket].socketDelegate = self;
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [ClientSocket shareSocket].socketDelegate = nil;
    [[ClientSocket shareSocket] disConn];
    [ClientSocket attempDealloc];
}

// IM
#pragma mark - ClientSocketDelegate
- (void)clientSocket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    NSLog(@"建立连接成功");
    [[ClientSocket shareSocket].socket readDataWithTimeout:-1 tag:101];
    [ClientSocket shareSocket].connectd = YES;
    // 开启定时器
    if ([ClientSocket shareSocket].connectTimer) {
        [[ClientSocket shareSocket].connectTimer invalidate];
        [ClientSocket shareSocket].connectTimer = nil;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [[ClientSocket shareSocket] addTimer];
    });
}

- (void)clientSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    
    if (100 == tag) {
        // 心跳
    }
    else if (101 == tag) {
        // conn
        NSString *text = [YZChatUtils convertDataToHexStr:data];
        NSString *printText = [NSString stringWithFormat:@"服务器返回--->%@",text];
        NSLog(@"%@",printText);
        char *str = (char *)[data bytes];
        unsigned char bts;
        unsigned long long r = varint_decode(str, 7, &bts);
        
        int btsLen = (int)bts;
        // 反序列化
        NSMutableString *realStr = [NSMutableString string];
        if (r * 2 <= text.length - btsLen * 2) {
            NSString *tempStr = [text substringWithRange:NSMakeRange(btsLen * 2, r * 2)];
            realStr = [NSMutableString stringWithString:tempStr];
            
            NSData *realData = [YZChatUtils dataFormHexString:realStr];
            ImMessage *p = [ImMessage parseFromData:realData error:nil];
            //            DLog(@"p>>>%@",p);
            
            // 打印确认接收报文日志
            if ([p.messageType isEqualToString:@"ack"]) {
                NSLog(@"收到服务器确认");
            } else if ([p.messageType isEqualToString:@"data"]) {
                NSLog(@"确认接收消息，发送ack消息");
                // 显示离线消息
                NSString *recStr = [[NSString alloc] initWithData:p.payload encoding:NSUTF8StringEncoding];
                NSString *showMsg = [NSString stringWithFormat:@"收到离线消息--->%@",recStr];
                NSLog(@"%@",showMsg);
                
                // 给服务器发送ack,确认收到离线消息
                [[ClientSocket shareSocket] doAck:p.messageId];
            };
        }
    } else {
        _allSize += data.length;
        [_allData appendData:data];
        NSLog(@"_allsize--->%ld",_allSize);
        [self readBytes:data];
    }
    
    
    // 继续接收数据
    [[ClientSocket shareSocket].socket readDataWithTimeout:-1 tag:0];
}

- (void)readBytes:(NSData *)data {
    // 过滤心跳包
    NSString *text = [YZChatUtils convertDataToHexStr:data];
    if ([self isDelayHeartRecData:text]) {
        NSLog(@"接收心跳OK");
        [ClientSocket shareSocket].receHearDt = [NSDate date];
        NSTimeInterval interlTimer = [[ClientSocket shareSocket].receHearDt timeIntervalSinceDate:[ClientSocket shareSocket].sendHeartDt];
        if (interlTimer < HEART_TIME * 2) {
            interlTimer = 0;
            return;
        } else {
            // 连接失效，客户端关闭socket并重新建立连接
            NSLog(@"心跳失效，重新连接");
            
            // 重新连接
            dispatch_async(dispatch_get_main_queue(), ^{
                [[ClientSocket shareSocket] autoConnection];
            });
        }
    }
    
    // 如果待读字节数大于0
    if (_bufferSize > 0) {
        if (data.length < _bufferSize) {
            // 继续读
            _bufferSize = _bufferSize - data.length;
            [_buffer appendData:data];
        } else {
            NSData *temp = [data subdataWithRange:NSMakeRange(0, _bufferSize)];
            [_buffer appendData:temp];
            // 解析数据
            ImMessage *p = [ImMessage parseFromData:_buffer error:nil];
            NSLog(@"p>>>%@",p);
            // 打印确认接收报文日志
            if ([p.messageType isEqualToString:@"ack"]) {
                NSLog(@"收到服务器确认");
            } else if ([p.messageType isEqualToString:@"data"]) {
                NSLog(@"确认接收消息，发送ack消息");
                // 显示离线消息
                NSString *recStr = [[NSString alloc] initWithData:p.payload encoding:NSUTF8StringEncoding];
                NSString *showMsg = [NSString stringWithFormat:@"收到离线消息--->%@",recStr];
                NSLog(@"%@",showMsg);
                // 刷新页面
                [self accpetMessage:p];
            };
            
            // 剩余的再处理一次
            NSUInteger leftInt = data.length - _bufferSize;
            if (leftInt > 0) {
                NSData *leftData = [data subdataWithRange:NSMakeRange(_bufferSize, data.length - _bufferSize)];
                
                // 重置buffer
                _bufferSize = 0;
                _buffer = [NSMutableData data];
                
                [self readBytes:leftData];
            } else {
                // 重置buffer
                _bufferSize = 0;
                _buffer = [NSMutableData data];
            }
        }
    } else {
        char *str = (char *)[data bytes];
        unsigned char bts;
        unsigned long long r = varint_decode(str, 7, &bts);
        int btsLen = (int)bts;
        if (data.length < r + btsLen) {
            _bufferSize = r - data.length + btsLen;
            NSData *appData = [data subdataWithRange:NSMakeRange(btsLen, data.length - btsLen)];
            [_buffer appendData:appData];
        } else if (data.length == r + btsLen) {
            // 解析数据
            NSData *tempData = [data subdataWithRange:NSMakeRange(btsLen, r)];
            ImMessage *p = [ImMessage parseFromData:tempData error:nil];
            NSLog(@"p>>>%@",p);
            
            // 打印确认接收报文日志
            if ([p.messageType isEqualToString:@"ack"]) {
                NSLog(@"收到服务器确认");
            } else if ([p.messageType isEqualToString:@"data"]) {
                NSLog(@"确认接收消息，发送ack消息");
                // 显示离线消息
                NSString *recStr = [[NSString alloc] initWithData:p.payload encoding:NSUTF8StringEncoding];
                NSString *showMsg = [NSString stringWithFormat:@"收到离线消息--->%@",recStr];
                NSLog(@"%@",showMsg);
                
                // 刷新页面
                [self accpetMessage:p];
                
                
            };
        } else if (data.length > r + btsLen) {
            // 粘包
            NSData *appData = [data subdataWithRange:NSMakeRange(r + btsLen + btsLen, data.length - r - btsLen - btsLen)];
            [_buffer appendData:appData];
            NSData *dealData = [data subdataWithRange:NSMakeRange(btsLen, r)];
            
            // 解析数据
            ImMessage *p = [ImMessage parseFromData:dealData error:nil];
            NSLog(@"p>>>%@",p);
            
            // 打印确认接收报文日志
            if ([p.messageType isEqualToString:@"ack"]) {
                NSLog(@"收到服务器确认");
            } else if ([p.messageType isEqualToString:@"data"]) {
                NSLog(@"确认接收消息，发送ack消息");
                // 显示离线消息
                NSString *recStr = [[NSString alloc] initWithData:p.payload encoding:NSUTF8StringEncoding];
                NSString *showMsg = [NSString stringWithFormat:@"收到离线消息--->%@",recStr];
                NSLog(@"%@",showMsg);
                // 刷新页面
                [self accpetMessage:p];
            };
            
            // 剩余的再处理一次
            NSUInteger leftInt = data.length - btsLen - r;
            if (leftInt > 0) {
                NSData *leftData = [data subdataWithRange:NSMakeRange(btsLen + r, data.length - btsLen - r)];
                
                // 重置buffer
                _bufferSize = 0;
                _buffer = [NSMutableData data];
                
                [self readBytes:leftData];
            } else {
                // 重置buffer
                _bufferSize = 0;
                _buffer = [NSMutableData data];
            }
        }
    }
}

#pragma mark - 发送消息核心方法
- (void)doSendMessage:(NSData *)dMessage
            mediaType:(NSString *)mediaType
          messageType:(NSString *)messType
             receiver:(NSString *)targetId{
    
    // 消息
    ImMessage *_mess = [YZChatUtils createMessage:@"YZIMP"
                                          version:@"1.0"
                                           userId:[YZUser sharedInstance].uid
                                        userToken:[YZUser sharedInstance].token
                                        messageId:1
                                      messageType:messType
                                      messageTime:[[YZChatUtils getTimeInterval2] integerValue] termType:@"iOS"
                                         receiver:targetId
                                           sender:[YZUser sharedInstance].uid
                                    ctrlMessageId:0
                                         playload:dMessage];
    NSLog(@"p>>>%@",_mess);
    
    // 序列化
    NSData *allData = [_mess data];
    
    // 消息长度
    unsigned long long number = [allData length];
    char* str = calloc(7, sizeof(char));
    unsigned char bts;
    varint_encode(number, str, 7, &bts);
    NSData *headVarint = [NSData dataWithBytes:str length:bts];
    NSLog(@"headVarint>>>%@",headVarint);
    free(str);
    
    // 总个消息
    NSMutableData *totalData = [NSMutableData dataWithData:headVarint];
    [totalData appendData:allData];
    
    [[ClientSocket shareSocket].socket writeData:totalData withTimeout:-1 tag:0];
    
}

- (void)accpetMessage:(ImMessage *)p {
}

- (void)sendAgree:(NSString *)targetId {
    
    NSDictionary *friendReqDic = @{@"action": @"addApproval",@"message":@""};
    
    NSData *sentData = [NSJSONSerialization dataWithJSONObject:friendReqDic options:NSJSONWritingPrettyPrinted error:nil];
    
    [self doSendMessage:sentData mediaType:@"application/json" messageType:@"friend" receiver:targetId];
}

#pragma mark - lazy load
- (UITableView *)newFriendTable {
    if (!_newFriendTable) {
        CGRect tableViewFrame = self.view.bounds;
        _newFriendTable = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStyleGrouped];
        _newFriendTable.delegate = self;
        _newFriendTable.dataSource = self;
        [_newFriendTable registerClass:[YZFriendBaseCell class] forCellReuseIdentifier:flagCell];
    }
    
    return _newFriendTable;
}

- (YZFriendVM *)viewModel{
    if (!_viewModel) {
        _viewModel = [[YZFriendVM alloc] init];
    }
    return _viewModel;
}

- (NSMutableArray *)newFriendData {
    if (!_newFriendData) {
        _newFriendData = [NSMutableArray array];
    }
    
    return _newFriendData;
}


#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.newFriendData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = indexPath.row;
    YZFriendBaseCell *cell = [tableView dequeueReusableCellWithIdentifier:flagCell];
    if (!cell) {
        cell = [[YZFriendBaseCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:flagCell];
        
    }
    cell.model = self.newFriendData[indexPath.row];
    
    NSString *targetId = cell.model.targetId;
    cell.cellBtnClickBlock = ^(BOOL agree) {
        
        if (agree) { // 同意
            @weakify(self)
            [[self.viewModel addFriend:targetId] subscribeNext:^(id  _Nullable x) {
                NSLog(@"x----->%@",x);
                
            } completed:^{
                @strongify(self);
                [self cellBtnClickAction:agree row:row];
                
                // 发送同意好友的消息
                [self performSelector:@selector(sendAgree:)
                           withObject:targetId
                           afterDelay:0.1];
            }];
        } else { // 拒绝
            [self cellBtnClickAction:agree row:row];
        }
    };
    
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 70;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
}

#pragma mark - refreshTable
- (void)cellBtnClickAction:(BOOL)agree row:(NSUInteger)row{
    
    YZFriendModel *model = self.newFriendData[row];
    // 刷新
    if (agree) {
        model.friendState = NewFriendStateAgreed;
    } else {
        model.friendState = NewFriendStateIgnored;
    }
    
    [self refreshTableFriendModel:model row:row];
    
    // 更新数据库
    BOOL insertSuccess = [self updateNewFriend:model];
    if (insertSuccess) {
        self.latestFriendArr = nil;
    }
    
    // 回调
    if (self.dealBlock) {
        self.dealBlock(YES);
    }
}

- (void)refreshTableFriendModel:(YZFriendModel *)friendModel
                            row:(NSUInteger)row{
    
    [self.newFriendData replaceObjectAtIndex:row withObject:friendModel];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.newFriendTable reloadData];
    });
    
}

- (BOOL)insertNewFriend:(YZFriendModel *)friendModel {
    
    BOOL success = [[YZDBManager sharedManage] insertNewFriendData:friendModel tableName:kNewFriendTable];
    if (success) {
//        [SVProgressHUD showSuccessWithStatus:@"处理成功"];
    }
    
    return success;
}

- (BOOL)updateNewFriend:(YZFriendModel *)friendModel {
    NSString *setStr = [NSString stringWithFormat:@"auditStatus = '%lu'",(unsigned long)friendModel.friendState];
    NSString *conditionStr = [NSString stringWithFormat:@"targetId = %@",friendModel.targetId];
    BOOL success = [[YZDBManager sharedManage] updateData:setStr table:kNewFriendTable andCondition:conditionStr];
    if (success) {
//        [SVProgressHUD showSuccessWithStatus:@"处理成功"];
    }
    
    return success;
}

#pragma mark - private
// 处理接收服务端返回心跳延迟的情况，心跳返回：100000
- (BOOL)isDelayHeartRecData:(NSString *)recStr{
    BOOL isDelay = NO;
    NSUInteger num = 0;
    NSUInteger len = recStr.length;
    num = [YZChatUtils cauculateTimer:recStr subStr:@"100000"];
    if (num > 0) {
        if (num * 6 == len) {
            isDelay = YES;
        }
    }
    
    return isDelay;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
